/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package g360.WebXpdlValidation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author andya
 */
public class TransformWrapper 
{
    private String xpdlVersion = "2.1";
    private ValidateXpdl caller = null;
    
    public TransformWrapper(ValidateXpdl caller, String version)
    {
        this.caller = caller;
        if (version != null)
        {
            this.xpdlVersion = version;
        }
    }
    
    public boolean runTransform(XpdlDomDocument xpdlDocument, PrintWriter out)
    {
        boolean result = false;
        try
        {
            ByteArrayInputStream input = xpdlDocument.getStream();
                
            javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(input);
            
            String transformFilePath = this.caller.getResourceManager().getTransformFilePath(this.xpdlVersion);
            InputStream inputStream = this.caller.getResourceManager().getInputStream(transformFilePath);
            javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(inputStream);
            ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream(); 
            StreamResult transformResults =  new javax.xml.transform.stream.StreamResult(byteArrayOutput);
 
            // create an instance of TransformerFactory
            javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance( );
 
            javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
            trans.transform(xmlSource, transformResults);
            
            String stringResults = byteArrayOutput.toString();
            if (false)
            {
                // Extract the content from the enclosing HTML document
                String startBody = "<body>";
                String endBody = "</body>";
                int start = stringResults.indexOf(startBody);
                int end = stringResults.indexOf(endBody);
                if ((start >= 0) && (end >= 0))
                {
                    String message = stringResults.substring(start + startBody.length(), end);
                    addMessage(message);
                }
            }
            else
            {
                // Remove all instances of the namespace declaration
                String namespaceString = "xmlns:xpdl=\"http://www.wfmc.org/2008/XPDL2.1\"";
                stringResults = stringResults.replaceAll(namespaceString, "");
                // Trim off the stuff before the first <p
                int index = stringResults.indexOf("<p");
                if (index > 0)
                {
                    stringResults = stringResults.substring(index);
                    addMessage(stringResults);
                }
            }
            result = true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            addMessage(ex.getMessage());
        }
        return result;
    }
    
    public boolean runTransformDOM(ByteArrayInputStream input, PrintWriter out)
    {
        boolean result = false;
        try
        {
            addMessage("This is a test of the transform notification system");
            addMessage("This is only a test.");
            input.reset();
                
            javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(input);
            
            String transformFilePath = this.caller.getResourceManager().getTransformFilePath(this.xpdlVersion);
            InputStream inputStream = this.caller.getResourceManager().getInputStream(transformFilePath);
            javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(inputStream);
            javax.xml.transform.dom.DOMResult transformResults =  new javax.xml.transform.dom.DOMResult();
 
            // create an instance of TransformerFactory
            javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance( );
 
            javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
            trans.transform(xmlSource, transformResults);
            Node head = transformResults.getNode();
            addMessage(head.getNodeName());
            walkTree(findNode("body", head));
            
            result = true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            addMessage(ex.getMessage());
        }
        return result;
    }
    
    protected Node findNode(String name, Node head)
    {
        if (head != null)
        {
            NodeList children = head.getChildNodes();
            for (int i = 0; i < children.getLength(); i++)
            {
                Node child = children.item(i);
                if (child.getNodeName().equals(name))
                {
                    return child;
                }
            }
        }
        return null;
    }
    
    protected void walkTree(Node head)
    {
        if (head != null)
        {
            NodeList children = head.getChildNodes();
            for (int i = 0; i < children.getLength(); i++)
            {
                Node child = children.item(i);
                if (child.getNodeType() == Node.TEXT_NODE)
                {
                    addMessage(child.getNodeValue());
                }
                else
                {
                    addMessage(child.getNodeName());
                }
                if (child.hasChildNodes())
                {
                    walkTree(child);
                }
            }
        }
    }
    
    private ArrayList<String> messages = new ArrayList<String>();
    
    public void clearMessages()
    {
        messages.clear();
    }
    
    public ArrayList<String> getMessages()
    {
        return messages;
    }
    
    protected void addMessage(String message)
    {
        this.messages.add(message);
    }

}
